﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SKDB_Matcher.SQL;
using SKDB_Matcher.SQL.DataTypeCompareResults;
using System.Collections;
using System.Data;

namespace SKDB_Matcher
{
    class CAlgorithm_DataType : CAbstractAlgorithm
    {
        private static Hashtable compareResults = generateResults();

        public CAlgorithm_DataType()
        {
            Weight = 0.2f;
            Caption = "DataTypeComparator";
        }

        private static Hashtable generateResults()
        {
            Hashtable result = new Hashtable();

            result.Add(CSQLDataType.DataType.dtChar, new CDataTypeCompareResultsChar());
            result.Add(CSQLDataType.DataType.dtDatetime, new CDataTypeCompareResultsDateTime());
            result.Add(CSQLDataType.DataType.dtDecimal, new CDataTypeCompareResultsDecimal());
            result.Add(CSQLDataType.DataType.dtInt, new CDataTypeCompareResultsInt());
            result.Add(CSQLDataType.DataType.dtMoney, new CDataTypeCompareResultsMoney());
            result.Add(CSQLDataType.DataType.dtNchar, new CDataTypeCompareResultsNChar());
            result.Add(CSQLDataType.DataType.dtSmallInt, new CDataTypeCompareResultsSmallInt());
            result.Add(CSQLDataType.DataType.dtText, new CDataTypeCompareResultsText());
            result.Add(CSQLDataType.DataType.dtTinyInt, new CDataTypeCompareResultsTinyInt());
            result.Add(CSQLDataType.DataType.dtvarchar, new CDataTypeCompareResultsVarchar());

            return result;
        }

       public static CAbstractCompareResult Compare(CSQLDataType _dataType1, CSQLDataType _dataType2)
       {
           return ((CAbstractDataTypeCompareResult)compareResults[_dataType1.getDataType()]).getCompareResult(_dataType2);
       }
        
       public CSQLDataType transformDataTypeToCSQLDataType(Type source)
       {
           CSQLDataType result = null;
           switch (source.FullName)
           {
               case "System.Byte"   : result = new CSQLDataType(CSQLDataType.DataType.dtTinyInt); break;
               case "System.Int16"  : result = new CSQLDataType(CSQLDataType.DataType.dtSmallInt); break;
               case "System.Int32"  : result = new CSQLDataType(CSQLDataType.DataType.dtInt); break;
               case "System.String" : result = new CSQLDataType(CSQLDataType.DataType.dtvarchar); break;
               case "System.Decimal": result = new CSQLDataType(CSQLDataType.DataType.dtDecimal); break;
               case "System.DateTime": result = new CSQLDataType(CSQLDataType.DataType.dtDatetime); break;
               default: result = new CSQLDataType(CSQLDataType.DataType.dtChar);
                   CConsole.WriteLine("Error: " + source.FullName + " is unknown!"); break;
           }
           return result;
       }

       override public float[,] CalcMatches(DataSet _Source, DataSet _Destination)
       {
           float[,] tmp = new float[SourceColumCount, TargetColumCount];
           int n = 0;
           int m = 0;
           foreach (DataTable TableSource in _Source.Tables)
           {
               foreach (DataColumn ColumnSource in TableSource.Columns)
               {
                   m = 0;
                   foreach (DataTable TableDest in _Destination.Tables)
                   {
                       foreach (DataColumn ColumnDest in TableDest.Columns)
                       {
                           CSQLDataType source = transformDataTypeToCSQLDataType(ColumnSource.DataType);
                           CSQLDataType target = transformDataTypeToCSQLDataType(ColumnDest.DataType);
                           tmp[n, m] = Compare(source,target).Value / 100f;
                           m++;
                       }
                   }
                   n++;
               }
           }
           return tmp;
       }
    }
}